﻿using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TinyEngine.Core.Asset;

namespace TinyEngine.Core.Services
{
    public delegate string GetRootHandler();
    public class AssetLibrary : ITinyService
    {
        private TinyGameEngine engine = null;
        public Dictionary<string, Asset.SpriteAsset> Sprites = null;
        public Dictionary<string, Asset.FontAsset> Fonts= null;
        public GetRootHandler GetContentRoot;

        public void Register()
        {
            engine = ServiceManager.GetService<TinyGameEngine>();
            
            Sprites = new Dictionary<string, Asset.SpriteAsset>();
            Fonts = new Dictionary<string, Asset.FontAsset>();

            CreateBasicTexture();
        }

        private void CreateBasicTexture()
        {
            Texture2D tex = new Texture2D(engine.Device, 1, 1);
            tex.SetData<Color>(new Color[] { Color.White });
            Sprites.Add("BasicTexture", new SpriteAsset("BasicTexture", tex));    
        }

        public SpriteAsset GetSprite(string name)
        {
            return Sprites[name];
        }

        public void UnRegister()
        {
            
        }

        internal FontAsset GetFont(string assetName)
        {
            return Fonts[assetName];
        }

        public void AddSprite(string name, string location, bool delayLoad) 
        {
            var item = new SpriteAsset(name, location);
            if (!delayLoad) 
                item.Load();
            
            this.Sprites.Add(name, item);
        }

        public void AddFont(string name, string location, bool delayLoad)
        {
            var item = new FontAsset(name, location);
            if (!delayLoad) 
                item.Load();

            this.Fonts.Add(name, item);
        }

        public void Save(string filename)
        {
            using (var st = new StreamWriter(filename))
            {

                foreach (var s in Sprites)
                {
                    if (s.Key == "BasicTexture") continue;

                    st.WriteLine(string.Format("{0}:{1}:{2}", "S", s.Key, s.Value.Location));
                }

                foreach (var s in Fonts)
                {
                    if (s.Key == "DEBUGFONT") continue;

                    st.WriteLine(string.Format("{0}:{1}:{2}", "F", s.Key, s.Value.Location));
                }
            }
        }

        public void LoadFrom(string filename)
        {
            LoadFrom(filename, false);
        }

        public void LoadFrom(string filename, bool delayLoad)
        {
            Stream stream = null;
            if (TinyGame.IsInEditor)
                stream = File.OpenRead(filename);
            else
                stream = TitleContainer.OpenStream(filename);
            
            var st = new StreamReader(stream);

            while (!st.EndOfStream)
            {
                var line = st.ReadLine();
                if (line.Trim() == string.Empty)
                {
                    break;
                }

                var split = line.Split(':');
                if (split[0] == "S")
                {
                    AddSprite(split[1], split[2], delayLoad);
                }
                else if (split[0] == "F")
                {
                    AddFont(split[1], split[2], delayLoad);
                }
            }

            st.Close();
            st.Dispose();
        }

        public void Unload()
        {
            this.Sprites.Clear();
            this.Fonts.Clear();

        }
    }
}
